package GuiInterfaced;


import com.jme3.app.SimpleApplication;
import com.jme3.collision.CollisionResults;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.export.binary.BinaryImporter;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.shadow.BasicShadowRenderer;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import com.jme3.scene.shape.*;
import com.jme3.scene.*;

import java.io.*;


/**
 * you can embed a jme canvas inside a swing application
 * @author pgi
 */
public class SwingCanvasTest extends SimpleApplication {
  float lwh;
  float x;
  float y;
  float z;
  Geometry cube;
  int numOfShapes;
  String whichShape="";
  boolean counter = false;
  PScreen newPS = new PScreen();
  public int SwingCanvasTest(){
      numOfShapes = 0;
      return numOfShapes;
  
  
  }
  //protected Geometry player2;
  //protected Geometry player3;
   Boolean isRunning =  true;
   
  @Override
  public void simpleInitApp() {
    // activate windowed input behaviour
    flyCam.setDragToRotate(true);
    initKeys();
    // display a cube
    //We need to make a variable that counts the number of shapes that are being rendered
    /*if (numOfShapes == 1)
    {
        x = 0;
        y = 0;
        z = 0;
    }else if(numOfShapes >= 2)
    {
        //location will depend on how big the last shape was...
    }*/
    
    /*
    cube = makeSquare("Box1", 0, 0, 0, 1);
    Geometry cube2 = makeSquare("Box2", 1,1,1, 1);
    rootNode.attachChild(cube);
    rootNode.attachChild(cube2);
    
     */
   /*cylinder myNewCylinder = new cylinder(3f, 2f, 0f,0f,0f);
    Material mCyl = new Material(assetManager,
                "Common/MatDefs/Misc/ShowNormals.j3md");
    Spatial newObject = myNewCylinder.createCylinder();
       newObject.setMaterial(mCyl);
    rootNode.attachChild(newObject);*/
    String newShapeMofo="";
    try {
    BufferedReader in = new BufferedReader(new FileReader("shapeFile.txt"));
    newShapeMofo=in.readLine();
    
    in.close();
} catch (IOException e) {
}
    
    if(newShapeMofo.equals("square")){
    triPrism myTriPrism = new triPrism(2f,1f,3f,0,0,0);
    Material mat = new Material(assetManager, 
            "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color",ColorRGBA.Blue);
    Spatial newObj = myTriPrism.createTriPrism();
    newObj.setMaterial(mat);
    rootNode.attachChild(newObj);
    
    triPrism myTriPrism1 = new triPrism(2f,1f,3f,0,0,0);
    Material mat1 = new Material(assetManager, 
            "Common/MatDefs/Misc/Unshaded.j3md");
    mat1.setColor("Color",ColorRGBA.Red);
    Geometry newObj1 = myTriPrism1.createEdges(.3f);
    newObj1.setMaterial(mat1);
    
    
    rootNode.attachChild(newObj1);
    System.out.println("textfile read square");
    }
    else if(counter==false)
    {
        counter = true;
        System.out.println("didn't read square in text file");
    }
    
        
    /*
    sphere rotateSphere = new sphere(1f, -1f, -1f,1f);
    Material sMat = new Material(assetManager,
            "Common/MatDefs/Misc/Unshaded.j3md");
    sMat.setColor("Color",ColorRGBA.Green);
    Spatial sObject = rotateSphere.createEdges();
    sObject.setMaterial(sMat);
    rootNode.attachChild(sObject);
    */
    /*
    Cylinder testCyl = new Cylinder(100, 50, 3, 4,true);
        testCyl.setMode(Mesh.Mode.Lines);
        testCyl.setLineWidth(4f);
        Geometry newCyl = new Geometry("lineCyl", testCyl);
        
        Material mCyl = new Material(assetManager,
                "Common/MatDefs/Misc/ShowNormals.j3md");
        newCyl.setLocalTranslation(1.5f,1.5f,1.5f);
        newCyl.setMaterial(mCyl);
        rootNode.attachChild(newCyl);
   */
    //Light and Shadow
    DirectionalLight sun = new DirectionalLight();
    sun.setColor(ColorRGBA.White);
    sun.setDirection(new Vector3f(-1, -1, 1).normalizeLocal());
    rootNode.addLight(sun);
    
    BasicShadowRenderer bsr;
    rootNode.setShadowMode(ShadowMode.Off);
    bsr = new BasicShadowRenderer(assetManager, 256);
    bsr.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
    viewPort.addProcessor(bsr);
    rootNode.updateGeometricState();
    
    
  }
  
 
  

  public static void main(String[] args) {
     
      
       /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(PScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(PScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(PScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(PScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
    java.awt.EventQueue.invokeLater(new Runnable() {

      public void run() {
        // create new JME appsettings
        AppSettings settings = new AppSettings(true);
        settings.setWidth(800);
        settings.setHeight(700);

        // create new canvas application
        SwingCanvasTest canvasApplication = new SwingCanvasTest();
        canvasApplication.setSettings(settings);
        canvasApplication.createCanvas(); // create canvas!
        JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication.getContext();
        ctx.setSystemListener(canvasApplication);
        Dimension dim = new Dimension(1242, 531);
        ctx.getCanvas().setPreferredSize(dim);

        // Create Swing window
        PScreen window = new PScreen();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Fill Swing window with canvas and swing components
        window.gamePanel.setLayout(new FlowLayout());// a panel
        window.gamePanel.add(ctx.getCanvas());                  // add JME canvas
           
       
            //whichShape = window.whatShapeToMake;
        
        // window.add(gamePanel);
        window.pack();

        // Display Swing window including JME canvas!
        window.setVisible(true);
        canvasApplication.startCanvas();
        
      }
    });
  }
  public static void setShape(String thisShape)
  {
      //whichShape = thisShape;
  }
 
  public Geometry makeSquare(String name, float x, float y, float z, float lwh)
  {
      Box box = new Box(new Vector3f(x, y, z), lwh, lwh, lwh);
      Geometry square = new Geometry(name, box);
      Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
      mat.setColor("Color", ColorRGBA.randomColor());
      square.setMaterial(mat);
      return square;
  }
  
  
  //Swing Components
  
  
  public Geometry makeRect(String name, float x, float y, float z, float l, float w, float h)
  {
      Box box = new Box(new Vector3f(x, y, z), l, w, h);
      Geometry rectangle = new Geometry(name, box);
      Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
      mat.setColor("Color", ColorRGBA.randomColor());
      rectangle.setMaterial(mat);
      return rectangle;
  }
  
  
  
  //Saving a Node
  @Override
  public void destroy()
  {
      String userHome = System.getProperty("user.home");
      BinaryExporter exporter = BinaryExporter.getInstance();
      File file = new File(userHome +"/someFile.j3o");
      try
      {
          exporter.save(rootNode, file);
      }catch(IOException ex){
          Logger.getLogger(SwingCanvasTest.class.getName()).log(Level.SEVERE,"Failed to save node!", ex);
      }
      super.destroy();
   }
  
  //Loading a Node
  public void loading()
  {
      String userHome = System.getProperty("user.home");
      BinaryImporter importer = BinaryImporter.getInstance();
      importer.setAssetManager(assetManager);
      File file = new File(userHome +"someFile.j3o");
      try{
          Node loadedNode = (Node)importer.load(file);
          loadedNode.setName("loaded node");
          rootNode.attachChild(loadedNode);
      }catch(IOException ex){
          Logger.getLogger(SwingCanvasTest.class.getName()).log(Level.SEVERE, "No saved node loaded!", ex);
      }
          
          
      }
  private void initKeys()
  {
      inputManager.setCursorVisible(true);
      inputManager.addMapping("select", new MouseButtonTrigger(mouseInput.BUTTON_LEFT));
      inputManager.addListener(analogListener, "select");
  }
  
  //The Selector Method
  private AnalogListener analogListener = new AnalogListener() {

        public void onAnalog(String name, float intensity, float tpf) {
           if(name.equals("select")){
               //Reset results list
               CollisionResults results = new CollisionResults();
               //Convert screen click to 3d position
               Vector2f click2d = inputManager.getCursorPosition();
               Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y),0f).clone();
               Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d);
               //Aim a ray from the click spot forwards
               Ray ray = new Ray(click3d, dir);
               //Collect intersections between ray and all nodes in results list
               rootNode.collideWith(ray, results);
               //Print so we know what is going on
               for(int i = 0; i < results.size(); i++){
                   //for each hit we know the distance impact point and geometry
                   float dist = results.getCollision(i).getDistance();
                   Vector3f pt = results.getCollision(i).getContactPoint();
                   String target = results.getCollision(i).getGeometry().getName();
                   System.out.println("Selection #"+ i + ":" + target + " at " + pt + ", " + dist + "WU away.");
             }
               //Use the results --we rotate the selected geom
               if(results.size() > 0){
                   //The closest result is the target that the player picked
                   Geometry target = results.getClosestCollision().getGeometry();
                  // Quaternion rollme = new Quaternion();
                   //rollme
                   //here is the actions
                   if(name.equals("select"))
                   {
                     target.rotate(0, -intensity, 0);
                   }
                   
               }
           }
        }
  };
}

/*
class cylinder extends Geometry
{
    private float radius, height, xPos,yPos,zPos;
    private String myName;
    public cylinder()
    {
        
    }
    public cylinder(String myName,float radius,float height)
    {
        
        this.radius = radius;
        this.height = height;
        this.myName=myName;
        
    }
    public Geometry createCylinder()
    {
        Cylinder testCyl = new Cylinder(100, 50, radius,height,true);
        testCyl.setMode(Mesh.Mode.Lines);
        testCyl.setLineWidth(4f);
        Geometry newCyl = new Geometry(myName, testCyl);
        
        //Material mCyl = new Material(assetManager,
         //       "Common/MatDefs/Misc/ShowNormals.j3md");
       // gCyl.setLocalTranslation(xPos,yPos,zPos);
        
       // gCyl.setMaterial(mCyl);
        return newCyl;
        //rootNode.attachChild(gCyl);
    }
    @Override
    public String getName()
    {
        return myName;
    }
}
 
 */